关于flutter:TabBarView具有动态容器高度

您所在的位置:网站首页 flutter tabbarview切换刷新 关于flutter:TabBarView具有动态容器高度

关于flutter:TabBarView具有动态容器高度

2023-09-05 20:27| 来源: 网络整理| 查看: 265

这是我的布局结构

这是主屏幕

123456ListView(   children: [     _buildCarousel(),     _buildHomeTabBar(),   ], )

这是HomeTabBar屏幕

12345678910111213141516171819202122232425SingleChildScrollView(   child:     DefaultTabController(       length: myTabs.length,       initialIndex: 0,       child: Column(         children: [           TabBar(             isScrollable: true,             tabs: myTabs,           ),           Container(             height: 600,               child:               TabBarView(                 children: [                   ChildScreen(),                   ChildScreen2(),                   ChildScreen3(),                 ],               )           )         ],       )) );

我想摆脱那个Container高度。 我们如何做到这一点?

ChildScreen从REST获取数据,它实际上是GridView.Builder,因此Container的高度应该是动态的。

抱歉,我实际上错过了ChildScreen的布局

12345678910111213141516171819202122232425SingleChildScrollView(   // shrinkWrap: true, child: Column(     children: [         StreamBuilder(           stream: categoryBloc.categoryList,           builder: (context, AsyncSnapshot snapshot){               if (snapshot.hasData && snapshot!=null) {                 if(snapshot.data.length > 0){                   return buildCategoryList(snapshot);                 }                 else if(snapshot.data.length==0){                     return Text('No Data');                 }               }               else if (snapshot.hasError) {                 return ErrorScreen(errMessage: snapshot.error.toString());               }                   return Center(child: CircularProgressIndicator());           },         ),           ]   ) );

因此,StreamBuilder内部是GridView.Builder。 我要删除的主要内容是Container高度。 在不同的设备上看起来很难看...

因此,如果我删除高度,它将不会显示在屏幕上并引发错误

I/flutter ( 493): #2 RenderObject.layout (package:flutter/src/rendering/object.dart:1578:12) I/flutter ( 493): #3 RenderSliverList.performLayout.advance (package:flutter/src/rendering/sliver_list.dart:200:17) I/flutter ( 493): #4 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:233:19) I/flutter ( 493): #5 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7) I/flutter ( 493): #6 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:182:11) I/flutter ( 493): #7 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7) I/flutter ( 493): #8 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:405:13) I/flutter ( 493): #9 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1316:12) I/flutter ( 493): #10 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1234:20) I/flutter ( 493): #11 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7) I/flutter ( 493): #12 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13) I/flutter ( 493): #13 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)

相关讨论 您会遇到什么错误-删除容器高度时。 -height: 600,? 它不会显示在屏幕上。 我将更新错误消息。 是GridView.Builder中的shrinkWrap: true,? @ anmol.majhail是GridView.Builder上的shrinkWrap: true

我在项目中也有类似的任务。问题的根源在于,您试图将TabBarView(尝试尽可能大的可滚动小部件)放在没有高度的列小部件中。

解决方案之一是摆脱在此示例ListView + Column中包装您的TabBarView的可滚动小部件。并使用NestedScrollView代替它们。您需要将_buildCarousel()和TabBar放在headerSliverBuilder部分中,并将TabBarView放在NestedScrollView主体内。

我不知道您的设计外观如何,但默认情况下NestedScrollView最多打开100%的屏幕视图高度。因此,如果您想使所有内容都在一个屏幕上,可以轻松地通过在需要时更改ScrollController行为来阻止滚动。

在此示例中,我禁止在第三个选项卡上滚动,但是您可以检查网格视图最后一项的可见性。只需将密钥添加到最后一项,然后检查其在屏幕上的位置即可。

希望对您有所帮助。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293class _MyHomePageState extends State with SingleTickerProviderStateMixin {   final bodyGlobalKey = GlobalKey();   final List myTabs = [     Tab(text: 'auto short'),     Tab(text: 'auto long'),     Tab(text: 'fixed'),   ];   TabController _tabController;   ScrollController _scrollController;   bool fixedScroll;   Widget _buildCarousel() {     return Stack(       children: [         Placeholder(fallbackHeight: 100),         Positioned.fill(child: Align(alignment: Alignment.center, child: Text('Slider'))),       ],     );   }   @override   void initState() {     _scrollController = ScrollController();     _scrollController.addListener(_scrollListener);     _tabController = TabController(length: 3, vsync: this);     _tabController.addListener(_smoothScrollToTop);     super.initState();   }   @override   void dispose() {     _tabController.dispose();     _scrollController.dispose();     super.dispose();   }   _scrollListener() {     if (fixedScroll) {       _scrollController.jumpTo(0);     }   }   _smoothScrollToTop() {     _scrollController.animateTo(       0,       duration: Duration(microseconds: 300),       curve: Curves.ease,     );     setState(() {       fixedScroll = _tabController.index == 2;     });   }   _buildTabContext(int lineCount) => Container(         child: ListView.builder(           physics: const ClampingScrollPhysics(),           itemCount: lineCount,           itemBuilder: (BuildContext context, int index) {             return Text('some content');           },         ),       );   @override   Widget build(BuildContext context) {     return Scaffold(       body: NestedScrollView(         controller: _scrollController,         headerSliverBuilder: (context, value) {           return [             SliverToBoxAdapter(child: _buildCarousel()),             SliverToBoxAdapter(               child: TabBar(                 controller: _tabController,                 labelColor: Colors.redAccent,                 isScrollable: true,                 tabs: myTabs,               ),             ),           ];         },         body: Container(           child: TabBarView(             controller: _tabController,             children: [_buildTabContext(2), _buildTabContext(200), _buildTabContext(2)],           ),         ),       ),     );   } }

获得所需内容的另一种方法是创建自定义TabView小部件。

相关讨论 不是OP,但是您可以显示示例代码吗? 我仍然停留在这里。 @Kherel Ketchil在将列表滚动到顶部时,如何在屏幕顶部保留标签栏? 确保我们只需要将TabBar从NestedScrollView的headerSliverBuilder部分移动到主体部分 与singlechildscrollview一起浪费了大约一个小时...非常感谢 经过6天的思考和尝试不同的方法。 这解决了我的问题。 谢谢 如果我必须在标题上粘贴标签栏呢? @ParthGodhani,您尝试将SliverPersistentHeader与pinned一起使用:true参数 整夜都在寻找解决方案。 谢谢! 如何保持向上滚动的选项卡不被隐藏在安全区域之外,当隐藏时,无法向下滚动。 徒劳了两天。 救命。

使用扩展小部件包装列表视图:

使用Expanded小部件可使Row,Column或Flex的子级展开以填充主轴上的可用空间(例如,水平放置为行,垂直放置为列)。如果扩展了多个子项,则会根据伸缩因子在可用空间之间进行分配。

12345678910111213Expanded(   child: ListView.builder(   itemCount: 120,   itemExtent: 32,   itemBuilder: (BuildContext context, int index) {     return new Row(       children: [         Icon(Icons.access_alarm),         Text(' Entry $index'),       ],     );   }, ))

相关讨论 不工作 抱歉,我错过了将要更新的ChildScreen的布局...



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3